﻿#pragma once
#include <vector>
#include <map>
#include <deque>
#include "def_spell.h"
#include "DB\DbTool.h"
#include <memory>
#include "Routine\Common\RoutineConfig.h"
#include "ClassDef.h"
#include "TalentMgr.h"
#include "BuffMgr.h"
#include "SpellTargetMgr.h"
#include "VariableMgr.h"
#include "PreviousMgr.h"
#include "ShipFormMgr.h"

// action
struct ActionSt {
	int type = -1;
	int spell_id = 0;
	int cool_down = -1;
	int in_range = 0;
	int key_index = 0;
	// charge
	int spell_charge_left = 0;
	int spell_charge_max = 0;
	int spell_charge_curr = 0;
	//
};
//
struct SpellConfig {
	int spell_id = -1;
	CString name_en;
	CString name_cn;
	int need_gcd = 0;
};
//
struct BuffOrDebuff {
	int spell_id = 0;
	int stack = 0;
	int duration = 0;
	int buff_or_debuff = 0;
	int cast_by_player = 0;
	bool Up()
	{
		return spell_id > 0;
	}

	bool Down() {
		return spell_id <= 0;
	}
};




struct TalentInfo
{
	int TalentID = 0;
	int row = -1;
	int column = -1;
	SpellID spell_id = SpellID_None;
};


using vec_aura = std::vector<BuffOrDebuff>;
using map_aura = std::map<int, BuffOrDebuff>;

struct Team_Raid_Info;

//
struct RuneInfo {
	int rune_slot_amount = 1;
	int rune_rest_time = 0;
};


class GameInfo {
public:
	GameInfo();
	~GameInfo();
	static GameInfo & inst();
	//////////////////////////////////////////////////////////////////////////

	void Init();

	bool ObtainInfo();

	void ObtainPetHp();

	void ObtainTargetDebuff();

	void ObtainPlayerBuff();

	void ObtainActionBarInfo();

	void ObtainActionBar(int line);

	void ObtainTargetHp();

	bool ObtainClassInfo();

	bool ObtainPlayerMana();

	bool ObtainPlayerHp();

	bool ObtainPlayerOtherInfo();

	void ObtainRuneInfo();

	void ObtainTeamAndRaid();

	size_t GetActionCount();

	ActionSt & GetActionByIndex(int index);

	ActionSt & GetActionByKeyIndex(int key_index);

	ActionSt & GetActionBySpellId(int spell_id);

	ActionSt * GetActionPtrBySpellId(int spell_id);

	bool IsActionNotCDAndInRange(int spell_id);

	bool SpellCostManaCheck(int spell_id);

	bool CheckSpellCanUse(int spell_id);

	double GetActionChargeFraction(int spell_id);

	int GetActionCDBySpellId(int spell_id);

	SpellConfig & GetSpellConfigBySpellID(int spell_id);

	BuffOrDebuff & GetPlayerBuff(int index);

	BuffOrDebuff & GetTargetDebuff(int index);

	BuffOrDebuff GetPlayerBuff(SpellID spell_id);

	RuneInfo & GetRune(int index);

	int GetTargetDebuffCD(int debuff_spell_id);

	int GetTargetDebuffStack(int spell_id);

	int GetPlayerBuffUp(int buff_spell_id);

	int GetPlayerBuffRemainTime(int buff_spell_id);

	int GetPlayerBuffStack(int spell_id);

	size_t GetPlayerBuffCount() const;
	size_t GetTargetDebuffCount() const;

	bool PlayerInBattle();
	bool TargetIsEnemy();

	int GetTargetHp() const;
	void SetTargetHp(int val);

	bool HasOpenPetUI();

	int GetPetHp() const;
	void SetPetHp(int val);

	int GetPlayerMana() const;
	void SetPlayerMana(int val);

	int GetRunicPowerDeficit();

	// 	int GetPlayerHpMax() const;
	// 	void SetPlayerHpMax(int val);

	// 	int GetPlayerHp() const;
	// 	void SetPlayerHp(int val);
	// 
	// 	double GetPlayerHpPercent();

	int GetRuneReadyCount() const;
	void SetRuneReadyCount(int val);

	int GetPlayerClass() const;
	void SetPlayerClass(int val);
	CString& GetPlayerClassName();

	int GetPlayerManaMax() const;
	void SetPlayerManaMax(int val);

	int GetFormID();

	int GetTargetHpMax() const;
	void SetTargetHpMax(int val);

	int GetGlobalCDExecute();

	int GetGlobalCD() const;
	void SetGlobalCD(int val);

	int GetTargetSpellCanInterupt() const;
	void SetTargetSpellCanInterupt(int val);

	void SetPartyInfo(int inParty, int PartyNum);
	void SetRaidInfo(int inRaid, int RaidNum);

	bool IsInParty();
	bool IsInRaid();

	int GetPartyNum();
	int GetRaidNum();

	double GetLostHP_InFiveSecond() const;
	void SetLostHP_InFiveSecond(double val);

	double GetElapseTime() const;
	void SetElapseTime(double val);

	int GetPlayerSpec() const;
	void SetPlayerSpec(int val);

	int GetPlayerSpecializationID() const;
	void SetPlayerSpecializationID(int val);

	int RuneTimeTo(int rune_count);

	bool GetShowInfo() const { return show_info_; }
	void SetShowInfo(bool val) { show_info_ = val; }

	bool IsTarget(std::string heal_target);

	bool IsTarget_Team_Raid(int n);

	bool GetIsPlayerIsTarget() const { return is_player_is_target; }
	void SetIsPlayerIsTarget(bool val) { is_player_is_target = val; }

	size_t GetTeam_Raid_Count();

	Team_Raid_Info& GetTeam_Raid_Item(int nIndex);

	bool IsPlayer_Channel_or_Casting();

	int GetPlayerExpectHealValue();
	int GetTargetExpectHealValue();

	Team_Raid_Info& GetTarget();

	Team_Raid_Info& GetPlayer();

	Team_Raid_Info* SpellByPlayer(SpellID spell_id);

	RoutineConfig& GetRoutineConfig();

	bool SatisfySpellCondition(std::string& name, SpecializationID speci_id, Team_Raid_Info& target);

	TalentMgr& talent();

	BuffMgr& buff();

	SpellTargetMgr& SpellTarget();
	VariableMgr& Variable();
	PreviousMgr& prev();
	ShipFormMgr& shiftform();

	bool Ap_Check(SpellID speed_id);
private:
	void InitSpellName();
	void InitProperty();

	void SaveAllPropertyDef();

	Property* FindProperty(InterfaceClassConfig& config, std::string& name);
	bool ConditionSatisfy(Property& prop, Team_Raid_Info& target);
private:
	using vec_action = std::vector<ActionSt>;
	using map_action = std::map<int, ActionSt>;
	using map_spell_config = std::map<int, SpellConfig>;
	vec_action vec_action_;
	map_action map_action_;
	int gcd_;	// 公共cd
	// buff of debuff

	using vec_rune = std::vector<RuneInfo>;
	vec_rune vec_rune_;

	//
	int has_pet_ui;
	int pet_hp;
	int pet_hp_max;

	std::shared_ptr<Team_Raid_Info> target_info;
	std::shared_ptr<Team_Raid_Info> player_info;

	// 	int player_hp;
	// 	int player_hp_max;
	// 	vec_aura player_buff_;
	// 	map_aura map_player_buff_;
	// 	int player_buff_count_;

	int last_loop_player_hp;
	DWORD time_begin_battle;
	struct lost_hp_record {
		int lost_value;
		DWORD time;
	};
	std::deque<lost_hp_record> dq_lost_hp;
	double total_lost_;
	double elapse_time;
	//
	int player_mana;
	int player_mana_max;
	//
	int mana_power_type;
	int power_type;
	int power_cur;
	int power_max;
	//
	int player_class;	// 玩家的职业  
	int player_spec;	// 玩家的专精
	int player_specialization_id;	// 玩家的职业ID
	bool is_player_is_target = false;	// 玩家是目标
	//
	int nFormID = 0;		// 变形ID
	//
	int ConRoSpellID = 0;	// ConRo 插件施法ID
	// 天赋
	int talent_count = 0;
	std::vector<TalentInfo> vec_talent;

	int runeReadyCount;
	int player_is_channel;
	int player_is_casting;
	//
	int target_is_enemy;
	int last_loop_in_battle;
	int in_battle;
	int target_spell_can_interupt;
	//
	int in_party;
	int party_num;
	int in_raid;
	int raid_num;
	bool show_info_ = false;

	TalentMgr talent_mgr;
	BuffMgr buff_mgr;

	RoutineConfig routine_config;
	map_spell_config map_spell_config_;


	SpellTargetMgr spell_target_;
	VariableMgr variable_;
	PreviousMgr prev_;
	ShipFormMgr shipform_;

	std::vector<std::shared_ptr<Team_Raid_Info>> vec_team_and_raid_;

	// 管理器
	friend class DbTool;
	friend class BuffMgr;

};
